package com.easylinkin.linkappapi.deviceattribute.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.easylinkin.linkappapi.common.exceptions.BusinessException;
import com.easylinkin.linkappapi.deviceattribute.entity.DeviceAttribute;
import com.easylinkin.linkappapi.deviceattribute.entity.DeviceAttributeTenantConfig;
import com.easylinkin.linkappapi.deviceattribute.mapper.DeviceAttributeTenantConfigMapper;
import com.easylinkin.linkappapi.deviceattribute.service.DeviceAttributeService;
import com.easylinkin.linkappapi.deviceattribute.service.DeviceAttributeTenantConfigService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import com.easylinkin.linkappapi.security.entity.LinkappUser;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

/**
 * <p>
 * 设备属性租户个性化配置 服务实现类
 * </p>
 *
 * @author TongJie
 * @since 2020-10-28
 */
@Service
public class DeviceAttributeTenantConfigServiceImpl extends ServiceImpl<DeviceAttributeTenantConfigMapper, DeviceAttributeTenantConfig> implements DeviceAttributeTenantConfigService {

    private static final Logger LOGGER = LoggerFactory.getLogger(DeviceAttributeTenantConfigServiceImpl.class);

    @Resource
    private LinkappUserContextProducer linkappUserContextProducer;

    @Resource
    private DeviceAttributeService deviceAttributeService;

    @Override
    public void batchSaveDeviceAttributeTenantConfigs(List<DeviceAttributeTenantConfig> deviceAttributeTenantConfigList) {
        Assert.notEmpty(deviceAttributeTenantConfigList, "deviceAttributeTenantConfigList 参数列表为空");

        int sortNo = 0;

        for (DeviceAttributeTenantConfig deviceAttributeTenantConfig : deviceAttributeTenantConfigList) {
            deviceAttributeTenantConfig.setSortNo(sortNo++);
            add(deviceAttributeTenantConfig);
        }
    }

    @Override
    public void add(DeviceAttributeTenantConfig deviceAttributeTenantConfig) {
        validParamRequired(deviceAttributeTenantConfig);
        validParamFormat(deviceAttributeTenantConfig);
        validRepeat(deviceAttributeTenantConfig);
        if (StringUtils.isEmpty(deviceAttributeTenantConfig.getTenantId())) {
            LinkappUser user = linkappUserContextProducer.getCurrent();
            deviceAttributeTenantConfig.setTenantId(user.getTenantId());
        }
        saveOrUpdate(deviceAttributeTenantConfig);
    }

    private void validRepeat(DeviceAttributeTenantConfig deviceAttributeTenantConfig) {
//        属性id + 租户id 不能重复
        QueryWrapper<DeviceAttributeTenantConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("device_attribute_id", deviceAttributeTenantConfig.getDeviceAttributeId());
        queryWrapper.eq("tenant_id", deviceAttributeTenantConfig.getTenantId());
        List<DeviceAttributeTenantConfig> list = baseMapper.selectList(queryWrapper);
        if (list.size() == 0) {
            return;
        }
        if (list.size() > 1) {
            throw new BusinessException("同租户下已存在相同的属性配置");
        }
        if (StringUtils.isEmpty(deviceAttributeTenantConfig.getId())) {
            throw new BusinessException("同租户下已存在相同的属性配置");
        }
        if (!deviceAttributeTenantConfig.getId().equals(list.get(0).getId())) {
            throw new BusinessException("同租户下已存在相同的属性配置");
        }
        
    }


    /**
     * 校验参数必填
     */
    private void validParamRequired(DeviceAttributeTenantConfig deviceAttributeTenantConfig) {
        Assert.notNull(deviceAttributeTenantConfig, "参数为空");
        Assert.notNull(deviceAttributeTenantConfig.getSortNo(), "参数'序号' 为空");
        Assert.notNull(deviceAttributeTenantConfig.getIsShow(), "参数'是否显示' 为空");
        Assert.isTrue(StringUtils.isNotBlank(deviceAttributeTenantConfig.getTenantId()), "租户id为空");
        Assert.isTrue(StringUtils.isNotBlank(deviceAttributeTenantConfig.getDeviceAttributeId()), "属性id 为空");
    }

    /**
     * 校验参数格式
     */
    private void validParamFormat(DeviceAttributeTenantConfig deviceAttributeTenantConfig) {
        Assert.isTrue(deviceAttributeTenantConfig.getDeviceAttributeId() == null || deviceAttributeTenantConfig.getDeviceAttributeId().length() <= 32, "deviceAttributeId 超长");
        Assert.isTrue(deviceAttributeTenantConfig.getTenantId() == null || deviceAttributeTenantConfig.getTenantId().length() <= 32, "租户id超长");
    }

    @Override
    public List<DeviceAttributeTenantConfig> getDeviceAttributeTenantConfigs(DeviceAttributeTenantConfig deviceAttributeTenantConfig) {
        if (StringUtils.isEmpty(deviceAttributeTenantConfig.getTenantId())) {
            deviceAttributeTenantConfig.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        }
        return baseMapper.getDeviceAttributeTenantConfigs(deviceAttributeTenantConfig);
    }

//    @Override
//    public void inheritPersonalizedConfig(Set<String> addDeviceAttrIds) {
//        if (ObjectUtils.isEmpty(addDeviceAttrIds)) {
//            return;
//        }
//        List<DeviceAttributeTenantConfig> deviceAttributeTenantConfigs = baseMapper.getLatestToBeUpdatedPersonalizedConfig(addDeviceAttrIds);
//
//        for (DeviceAttributeTenantConfig deviceAttributeTenantConfig : deviceAttributeTenantConfigs) {
//            if (deviceAttributeTenantConfig.getIsShow() == null) {
//                deviceAttributeTenantConfig.setIsShow(false);
//            }
//            if (deviceAttributeTenantConfig.getSortNo() == null) {
//                deviceAttributeTenantConfig.setSortNo(0);
//            }
//            updateById(deviceAttributeTenantConfig);
//        }
//// 当同时用到了 高版本和低版本对应的 属性id 删除与低版本的关联 只保留高的
//        baseMapper.deleteAttrIdentifierRepeatData();
//
//        //  如果 linkthings有新增的属性 需要插入到个性化配置中，默认设置为不可见
//        List<DeviceAttributeTenantConfig> deviceAttributeTenantConfigList = baseMapper.getNeedAddConfigAfterInheritPersonalizedConfig();
//        for (DeviceAttributeTenantConfig deviceAttributeTenantConfig : deviceAttributeTenantConfigList) {
//            deviceAttributeTenantConfig.setSortNo(0);
//            deviceAttributeTenantConfig.setIsShow(false);
//            save(deviceAttributeTenantConfig);
//        }
//// 清理 重复数据 attr_id +tenant_id
////        baseMapper.deleteAttrIdentifierRepeatData2();
//
//    }

    @Override
    public void inheritPersonalizedConfig(String existRefId, String tenantId, String newDeviceUnitId) {
        //1、删除掉这个项目下已经配置的属性
        deleteByTenantIdAndUnitId(tenantId,existRefId);
        deleteByTenantIdAndUnitId(tenantId,newDeviceUnitId);
        //2、新增对应的配置
        DeviceAttribute deviceAttr = new DeviceAttribute().setDeviceUnitId(newDeviceUnitId);
        List<DeviceAttribute> deviceAttrList = deviceAttributeService.getAll2(deviceAttr);
        if(!CollectionUtils.isEmpty(deviceAttrList)){
            for (DeviceAttribute deviceAttribute : deviceAttrList) {
                DeviceAttributeTenantConfig deviceAttributeTenantConfig = new DeviceAttributeTenantConfig();
                deviceAttributeTenantConfig.setDeviceAttributeId(deviceAttribute.getId());
                deviceAttributeTenantConfig.setTenantId(tenantId);
                deviceAttributeTenantConfig.setIsShow(deviceAttribute.getIsShow());
                deviceAttributeTenantConfig.setSortNo(deviceAttribute.getSortNo());
                save(deviceAttributeTenantConfig);
            }
        }
    }

    @Override
    public void deleteByTenantIdAndUnitId(String tenantId, String existRefId) {
        DeviceAttribute oldAttr = new DeviceAttribute().setDeviceUnitId(existRefId);
        List<DeviceAttribute> oldAttrs = deviceAttributeService.getAll2(oldAttr);
        if(!CollectionUtils.isEmpty(oldAttrs)){
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("tenant_id",tenantId);
            queryWrapper.in("device_attribute_id", oldAttrs.stream().map(DeviceAttribute::getId).collect(Collectors.toList()));
            baseMapper.delete(queryWrapper);
        }
    }
}
